<pre>
<script>

function compileRegExp(xregexp, name) {
  if (xregexp[name] instanceof RegExp) {
    return xregexp[name].source
  }
  let regexp = xregexp[name].replace(/\<([^>]+)\>/g, (str, $1) => {
    return compileRegExp(xregexp, $1)
  })
  return regexp
}

function scan(str) {
  let regexp = new RegExp(compileRegExp({
    InputElement: "<Whitespace>|<LineTerminator>|<Comments>|<Token>",
    Whitespace: / /,
    LineTerminator: /\n/,
    Comments: /\/\*([^*]\*[^\/])*\*\/|\/\/[^\n]*/,
    Token: "<Literal>|<Keywords>|<Identifer>|<Punctuator>",
    Literal: "<NumbericLiteral>|<BooleanLiteral>|<StringLiteral>|<NullnLiteral>",
    NumbericLiteral: /([1-9][0-9]*|0)(\.[0-9]*)?|\.[0-9]+/,
    BooleanLiteral: /true|false/,
    StringLiteral: /\"([^"\n]|\\[\s\S])*\"|\'([^'\n]|\\[\s\S])*\'/,
    NullnLiteral: /null/,
    Identifer: /[a-zA-Z_$][a-zA-Z0-9_$]*/,
    Keywords: /if|else|for|function|let/,
    Punctuator: /\+|\,|\?|\:|\{|\}|\.|\(|\=|\<|\+\+|\=\=|\=\>|\*|\)|\[|\];/,
  }, 'InputElement'), 'g')
  while(regexp.lastIndex < str.length) {
    let r = regexp.exec(str)
    console.log(JSON.stringify(r[0]))
    document.write(r[0])
    if (!r[0].length) {
      break
    }
  }
}

scan(`
  for (let i = 0; i < 3; i++) {
    for (let j = 0; j < 3; j++) {
      let cell = document.createElement('div');
      cell.classList.add('cell');
      cell.innerText = pattern[i * 3 + j] == 2 ? "X" :
        pattern[i * 3 + j] == 1 ? "O" : '';
      cell.addEventListener('click', () => userMove(j, i));
      board.appendChild(cell);
    }
    board.appendChild(document.createElement('br'))
  }
`)

</script>
</pre>